/*-----------------------------------------------------------------------------
	The contents of this file are subject to the Mozilla Public License
	Version 1.1 (the "License"); you may not use this file except in
	compliance with the License. You may obtain a copy of the License at
	http://www.mozilla.org/MPL/
	
	Software distributed under the License is distributed on an "AS IS"
	basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
	License for the specific language governing rights and limitations
	under the License.
	
	The Original Code is Fever Framework code.
	
	The Initial Developer of the Original Code is Romain Ecarnot.
	Portions created by Initial Developer are Copyright (C) 2006
	the Initial Developer. All Rights Reserved.
	
	Contributor(s):
	
	Unless required by applicable law or agreed to in writing, software
	distributed under the License is distributed on an "AS IS" BASIS,
	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
	See the License for the specific language governing permissions and
	limitations under the License.
-----------------------------------------------------------------------------*/

import org.aswing.ASWingUtils;
import org.aswing.border.EmptyBorder;
import org.aswing.BorderLayout;
import org.aswing.Component;
import org.aswing.Container;
import org.aswing.geom.Dimension;
import org.aswing.geom.Point;
import org.aswing.Insets;
import org.aswing.JButton;
import org.aswing.JComboBox;
import org.aswing.JFrame;
import org.aswing.JLabel;
import org.aswing.JList;
import org.aswing.JPanel;
import org.aswing.JScrollPane;
import org.aswing.JSeparator;
import org.aswing.JTextField;
import org.aswing.ListCell;
import org.aswing.SoftBox;
import org.aswing.SoftBoxLayout;
import org.aswing.VectorListModel;

import com.bourre.commands.Command;
import com.bourre.data.collections.IndexedArray;
import com.bourre.data.iterator.Iterator;
import com.bourre.events.BasicEvent;
import com.bourre.events.BooleanEvent;
import com.bourre.mvc.AbstractView;

import fever.data.file.File;
import fever.data.file.FileFilter;
import fever.data.file.FileUploader;
import fever.data.file.FileUploaderEvent;
import fever.display.ModalScreen;
import fever.events.FeverController;
import fever.events.FeverEventList;
import fever.Fever;
import fever.utils.Stringifier;
import fever.utils.StringUtil;

import fvaswing.components.filechooser.cells.FvFileChooserCellFactory;
import fvaswing.components.filechooser.events.FvFileChooserCommander;
import fvaswing.components.filechooser.events.FvFileChooserEventList;
import fvaswing.components.filechooser.events.FvFileChooserModelEvent;
import fvaswing.components.filechooser.FvFileChooserResources;
import fvaswing.components.filechooser.mvc.FvFileChooserController;
import fvaswing.components.filechooser.mvc.FvFileChooserModel;
import fvaswing.components.filechooser.preview.FvChooserPreview;
import fvaswing.components.FvButton;
import fvaswing.components.FvFileChooser;
import fvaswing.components.FvInputComponentDialog;
import fvaswing.components.FvLabelButton;
import fvaswing.components.input.FvTextFieldInput;

/**
 * <strong>FvFileChooserView</strong> is the <strong>view</strong> 
 * part of the <strong>MVC Design pattern</strong> implemented in 
 * {@link fvaswing.components.FvFileChooser}.
 * 
 * <p>All component behaviours and graphics are defined here.
 * 
 * @author Romain Ecarnot
 */
class fvaswing.components.filechooser.mvc.FvFileChooserView extends AbstractView
{
	//-------------------------------------------------------------------------
	// Events definition
	//-------------------------------------------------------------------------
	
	/**
	 * Constant. Unique ID for {@link fvaswing.components.filechooser.preview.FvChooserPreview} 
	 * instance.
	 * 
	 * <p>Use by the {@link fvaswing.visual.FvViewHelper} API.
	 */
	public static var PREVIEW : String = 'PreviewComponentUI';
	
	
	//-------------------------------------------------------------------------
	// Private properties
	//-------------------------------------------------------------------------
	
	private var _frame : JFrame;
	private var _modalTarget : MovieClip;
	
	private var _modal : ModalScreen;
	
	private var _dimToolbarButton : Dimension;
	
	private var _lblLookIn : JLabel;
	private var _cmbLookIn : JComboBox;
	private var _btnRefresh : FvLabelButton;	private var _btnParent : FvLabelButton;
	private var _btnHome : FvLabelButton;
	private var _btnUpload : FvLabelButton;	private var _btnCreate : FvLabelButton;
	
	private var _view : Component;
	
	private var _lblFileName : JLabel;
	private var _inputFileName : JTextField;
	private var _lblFileType : JLabel;
	private var _cmbFileType : JComboBox;
	private var _cmbFileTypeModel : VectorListModel;
	private var _btnApprouve : FvButton;
	private var _btnCancel : FvButton;
	
	private var _mainContener : JPanel;	private var _previewComponent : FvChooserPreview;
	
	private var _scroll : JScrollPane;
	private var _list : JList;
	
	private var _data : Array;
	private var _dataFiltered : Array;
	private var _storedPath : String;
	private var _storedSelection : Array;
	
	private var _pendingUpdate : Boolean;
	private var _pendingResult : Boolean;
	
	private var _type : Number;

	private var _mainToolbar : Container;
	
	private var _uploader : FileUploader;
	private var _lockUpload : ModalScreen;
	private var _title : String;
	
	private var _inputFolderDialog : FvInputComponentDialog;
	
	
	//-------------------------------------------------------------------------
	// Public API
	//-------------------------------------------------------------------------
	
	/**
	 * Constructor.
	 */
	public function FvFileChooserView( m : FvFileChooserModel, c : FvFileChooserController )
	{
		super( m, c, null );
		
		_uploader = new FileUploader();
		_uploader.addEventListener( FileUploader.UPLOAD_START, this, _onUploadStart );
		_uploader.addEventListener( FileUploader.UPLOAD_PROGRESS, this, _onUploadProgress  );
		_uploader.addEventListener( FileUploader.UPLOAD_COMPLETE, this, _onUploadComplete );		_uploader.addEventListener( FileUploader.UPLOAD_ERROR, this, _onUpLoadError );
				_pendingUpdate = false;
		
		_configureUI();
	}
	
	/**
	 * Apply user-defined filters.
	 */
	public function setType( type : Number, filter : IndexedArray, defaultFilter : FileFilter, caption : String, enabled : Boolean ) : Void
	{
		_uploader.cleanFilter();
		
		var it : Iterator = filter.getIterator();
		
		while( it.hasNext() ) _uploader.addFilter( it.next() );
		
		//TODO check "defaultFilter" parameter to select default filter when dialog open
		
		_cmbFileTypeModel.clear();
		_cmbFileTypeModel.appendAll( filter.getElements() );
		_cmbFileType.setSelectedIndex( 0 );
		
		_handleChangeFilter( _cmbFileType );
		
		switch( type )
		{
			case FvFileChooserResources.OPEN :
				_btnApprouve.setText( FvFileChooserResources.getInstance().openLabel );
				_frame.setTitle( FvFileChooserResources.getInstance().openLabel );
				_setFilePropertiesVisible( true );	
				_list.setSelectionMode( 
					getController().isMultiSelectionEnabled() 
						? JList.MULTIPLE_SELECTION 
						: JList.SINGLE_SELECTION 
				);
				break;
				
			case FvFileChooserResources.SAVE :
				_btnApprouve.setText( FvFileChooserResources.getInstance().saveLabel );
				_frame.setTitle( FvFileChooserResources.getInstance().saveLabel );
				_setFilePropertiesVisible( true );
				_list.setSelectionMode( JList.SINGLE_SELECTION );
				break;
			
			case FvFileChooserResources.BROWSE :
				_btnApprouve.setText( FvFileChooserResources.getInstance().folderLabel );
				_frame.setTitle( FvFileChooserResources.getInstance().folderLabel );
				_setFilePropertiesVisible( false );
				_list.setSelectionMode( JList.SINGLE_SELECTION );
				break;
				
			case FvFileChooserResources.CUSTOM :
				_btnApprouve.setText( caption );
				_frame.setTitle( caption );
				_setFilePropertiesVisible( true );
				_list.setSelectionMode( 
					getController().isMultiSelectionEnabled() 
						? JList.MULTIPLE_SELECTION 
						: JList.SINGLE_SELECTION 
				);
				break;
		}
		
		_type = type;
		
		_updateLocalisation();
	}
	
	/**
	 * Opens dialog
	 */
	public function show() : Void
	{
		_checkPreviewComponent();
		_checkUploadButton();
		
		_resetSelection();
		_pendingResult = false;
		_layout();
		
		_modal.show();
		_frame.show();
	}
	
	/**
	 * Receives model data
	 */
	public function onListUpdate( e : FvFileChooserModelEvent ) : Void
	{
		_pendingUpdate = true;
		
		_resetSelection();
		_previewComponent.reset();
		
		_cmbLookIn.setListData( e.getCacheList() );
		_cmbLookIn.setSelectedItem( e.getCurrentPath() );
		_filterData( e.getFileList() );
		
		_pendingUpdate = false;
		
		getController().unlockUI();
	}
	
	/**
	 * Receives model error
	 */
	public function onListError( e : FvFileChooserModelEvent ) : Void
	{
		//TODO Model error managment
	}
	
	/**
	 * Returns {@link IController} associated with this view.
	 * 
	 * @return {@link FvFileChooserController} instance
	 */
	public function getController() : FvFileChooserController
	{
		return FvFileChooserController( _oController );	
	}
	
	/**
	 * Adds type to preview loader.
	 */
	public function addPreviewCommand( type : String, previewCommand : Command ) : Void
	{
		_previewComponent.addPreviewCommand( type, previewCommand );
	}
	
	/**
	 * Returns string representation.
	 */
	public function toString() : String
	{
		return Stringifier.parse( this );
	}
	
	
	//-------------------------------------------------------------------------
	// Private implementation
	//-------------------------------------------------------------------------
	
	/**
	 * Prepares alert UI.
	 */
	private function _configureUI() : Void
	{
		_dimToolbarButton = new Dimension( 20, 20 );
		
		_configureBasedFrame();
		
		_frame.getContentPane().append( _createNorthPanel(), BorderLayout.NORTH );
		_frame.getContentPane().append( _createCenterPanel(), BorderLayout.CENTER );
		_frame.getContentPane().append( _createSouthPanel(), BorderLayout.SOUTH );
		
		var input : FvTextFieldInput = new FvTextFieldInput();
		input.setRestrict( 'a-z A-Z 0-9_-' );
		
		_inputFolderDialog = new FvInputComponentDialog( input );
	}
	
	private function _getModalTarget() : MovieClip
	{
		_modal.dispose();
		_modal = new ModalScreen( 0x000000, 0 );
		
		return _modal.getModalTarget();
	}
	
	/**
	 * Configures the based {@code JFrame} container.
	 */
	private function _configureBasedFrame() : Void
	{
		_frame = new JFrame( _getModalTarget(), "", false );
		_frame.setResizable( true );
		_frame.setClosable( true );
		_frame.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
		_frame.setMinimumSize( new Dimension( 400, 275 ) );
		_frame.setSize( new Dimension( 400, 275 ) );
		
		_frame.addEventListener( JFrame.ON_WINDOW_OPENED, _handleInit, this );
		_frame.addEventListener( JFrame.ON_WINDOW_CLOSING, _handleCloseChooser, this );		
		_frame.getContentPane().setBorder( new EmptyBorder( null, new Insets( 5, 5, 5, 5 ) ) );
		_frame.getContentPane().setLayout( new BorderLayout( 5, 5 ) );
	}
	
	/**
	 * Calculates a new frame position.
	 */
	private function _layout() : Void
	{
		var location : Point = ASWingUtils.getScreenCenterPosition();
		location.x -= _frame.getWidth()/2;
		location.y -= _frame.getHeight()/2;
		_frame.setLocation( location );
	}
	
	/**
	 * Creates and returns notrh panel
	 */
	private function _createNorthPanel() : JPanel
	{
		_lblLookIn = new JLabel( FvFileChooserResources.getInstance().lookInLabel, JLabel.LEFT );
		
		_cmbLookIn = new JComboBox();
		_cmbLookIn.addActionListener( _handleMoveTo, this );
		
		_btnRefresh = new FvLabelButton( FvFileChooserResources.getInstance().refreshIcon );
		_btnRefresh.setPreferredSize( _dimToolbarButton );
		_btnRefresh.addActionListener( _handleRefresh, this );
		_btnRefresh.setUseHandCursor( false );
		
		_btnParent = new FvLabelButton( FvFileChooserResources.getInstance().parentIcon );
		_btnParent.setPreferredSize( _dimToolbarButton );
		_btnParent.addActionListener( _handleMoveUp, this );
		_btnParent.setUseHandCursor( false );
		
		_btnHome = new FvLabelButton( FvFileChooserResources.getInstance().homeIcon );
		_btnHome.setPreferredSize( _dimToolbarButton );
		_btnHome.addActionListener( _handleMoveToHome, this );
		_btnHome.setUseHandCursor( false );
		
		_btnUpload = new FvLabelButton( FvFileChooserResources.getInstance().uploadIcon );
		_btnUpload.setPreferredSize( _dimToolbarButton );
		_btnUpload.addActionListener( _handleUpload, this );
		_btnUpload.setUseHandCursor( false );
		
		_btnCreate = new FvLabelButton( FvFileChooserResources.getInstance().createIcon );
		_btnCreate.setPreferredSize( _dimToolbarButton );
		_btnCreate.addActionListener( _handleCreate, this );
		_btnCreate.setUseHandCursor( false );
		
		_mainToolbar = new SoftBox( SoftBoxLayout.X_AXIS, 5 );
		_mainToolbar.append( _btnParent );
		_mainToolbar.append( _btnHome );
		_mainToolbar.append( new JSeparator( JSeparator.VERTICAL ) );
		_mainToolbar.append( _btnRefresh );
		_mainToolbar.append( _btnUpload );		_mainToolbar.append( _btnCreate );
		
		var p : JPanel = new JPanel( new BorderLayout( 5,5 ) );
		p.append( _lblLookIn, BorderLayout.WEST );
		p.append( _cmbLookIn, BorderLayout.CENTER );
		p.append( _mainToolbar, BorderLayout.EAST );
		return p;
	}
	
	/**
	 * Creates and returns center panel ( Files list view )
	 */
	private function _createCenterPanel() : JPanel
	{
		_mainContener = new JPanel( new BorderLayout( 5,5 ) );
		_mainContener.append( _getListView(), BorderLayout.CENTER ) ;
		return _mainContener;
	}
	
	/**
	 * Creates and returns south panel
	 */
	private function _createSouthPanel() : JPanel
	{
		_lblFileName = new JLabel( FvFileChooserResources.getInstance().fileNameLabel, JLabel.LEFT );
		_lblFileType = new JLabel( FvFileChooserResources.getInstance().fileTypeLabel, JLabel.LEFT );
		
		var prefSize : Number = Math.max( _lblFileName.getPreferredWidth(), _lblFileType.getPreferredWidth() );
		prefSize = Math.max( prefSize, _lblLookIn.getPreferredWidth() );
		
		_lblFileName.setPreferredWidth( prefSize );		_lblFileType.setPreferredWidth( prefSize );
		_lblLookIn.setPreferredWidth( prefSize );
		
		_inputFileName = new JTextField();
		
		_cmbFileTypeModel = new VectorListModel();
		_cmbFileType = new JComboBox( _cmbFileTypeModel );
		_cmbFileType.addActionListener( _handleChangeFilter, this );
		
		_btnApprouve = new FvButton( FvFileChooserResources.getInstance().openLabel );
		_btnApprouve.addActionListener( _handleOpenItem, this );
		
		_btnCancel = new FvButton( FvFileChooserResources.getInstance().cancelLabel );
		_btnCancel.addActionListener( _handleCloseChooser, this );
		
		prefSize = Math.max( _btnApprouve.getPreferredWidth(), _btnCancel.getPreferredWidth() );
		prefSize = Math.max( prefSize, 100 );
		_btnApprouve.setPreferredWidth( prefSize );		_btnCancel.setPreferredWidth( prefSize );
		
		var line1 : JPanel = new JPanel( new BorderLayout( 5,5 ) );
		line1.append( _lblFileName, BorderLayout.WEST );
		line1.append( _inputFileName, BorderLayout.CENTER );
		
		var line2 : JPanel = new JPanel( new BorderLayout( 5,5 ) );
		line2.append( _lblFileType, BorderLayout.WEST );
		line2.append( _cmbFileType, BorderLayout.CENTER );
		
		var line3 : JPanel = new JPanel( new SoftBoxLayout( SoftBoxLayout.X_AXIS, 5, SoftBoxLayout.RIGHT ) );
		line3.append( _btnApprouve );
		line3.append( _btnCancel );
		
		var p : JPanel = new JPanel( new SoftBoxLayout( SoftBoxLayout.Y_AXIS, 5 ) );
		p.append( line1 );		p.append( line2 );		p.append( line3 );
		return p;
	}
	
	private function _checkPreviewComponent() : Void
	{
		if( getController().isPreviewEnabled() )
		{
			if( !_previewComponent )
			{
				_previewComponent = new FvChooserPreview();
				_mainContener.append( _previewComponent.getContainer(), BorderLayout.EAST );
			}
			
			_previewComponent.init( _modalTarget );
			_previewComponent.reset();
			_previewComponent.getContainer().setVisible( true );
		}
		else _previewComponent.getContainer().setVisible( false );
	}
	
	private function _checkUploadButton() : Void
	{
		if( getController().isUploadEnabled() )
		{
			if( !_mainToolbar.contains( _btnUpload ) ) _mainToolbar.append( _btnUpload );
		}
		else _mainToolbar.remove( _btnUpload );
	}
	
	/**
	 * Updates UI Localisation
	 */
	private function _updateLocalisation() : Void
	{
		_lblLookIn.setText( FvFileChooserResources.getInstance().lookInLabel  );			_lblFileName.setText( FvFileChooserResources.getInstance().fileNameLabel );			_lblFileType.setText( FvFileChooserResources.getInstance().fileTypeLabel );
		
		_btnCancel.setText( FvFileChooserResources.getInstance().cancelLabel );
	}
	
	/**
	 * Creates and returns the main JList view
	 */
	private function _getListView() : Component
	{
		if( !_list )
		{
			_list = new JList( null, new FvFileChooserCellFactory( false, true ) );
			_list.setSelectionMode( JList.SINGLE_SELECTION );
			_list.setOpaque( true );
			
			_list.addEventListener( JList.ON_ITEM_CLICKED, _handleListClick, this );
			_list.addEventListener( JList.ON_KEY_DOWN, _handleListKeyDown, this );
			
			_scroll = new JScrollPane( _list, JScrollPane.SCROLLBAR_AS_NEEDED, JScrollPane.SCROLLBAR_AS_NEEDED );
		}
		return _scroll;	
	}
	
	/**
	 * Toggle file specific components visibility
	 */
	private function _setFilePropertiesVisible( b : Boolean ) : Void
	{
		_lblFileName.setVisible( b );
		_lblFileType.setVisible( b );
		_inputFileName.setVisible( b );
		_cmbFileType.setVisible( b );	
	}
	
	/**
	 * Triggered when user click on 'approuve' button.
	 */
	private function _handleOpenItem( source : JButton ) : Void
	{
		if( _type == FvFileChooserResources.BROWSE )
		{
			if( _list.getSelectedValue() )
			{
				_storedPath = _cmbLookIn.getSelectedItem().toString();
				var item : File = File( _list.getSelectedValue() );
				_storedSelection = new Array( item );
				
				_preventCloseFrame();
				_sendResultToController( FvFileChooser.APPROUVE_OPTION );
				return;
			}	
		}
		
		if( File( _list.getSelectedValue() ).isDirectory() )
		{
			_openDirectory( File( _list.getSelectedValue() ) );	
		}
		else
		{
			_inputFileName.setText( StringUtil.trim( _inputFileName.getText() ) );
			
			if( _inputFileName.getTextLength() > 0 )
			{
				if( ( _type == FvFileChooserResources.OPEN && _isAvailableFile() ) ||   _type == FvFileChooserResources.SAVE )
				{
					_buildResultData();	
				}
			}
		}
	}
	
	/**
	 * Builds selection data ( array )
	 */
	private function _buildResultData() : Void
	{
		_buildSelectionData();
		
		_preventCloseFrame();
		
		_sendResultToController( FvFileChooser.APPROUVE_OPTION );	
	}
	
	/**
	 * Closes JFrame without dispatch 'CANCEL_OPTION' event
	 */
	private function _preventCloseFrame() : Void
	{
		_pendingResult = true;
		_close();
		_pendingResult = false;	
	}
	
	/**
	 * Triggered by the 'cancel' button.
	 * 
	 * <p>Just close the JFrame and dispatch event to notify user.
	 */
	private function _handleCloseChooser( source : JButton ) : Void
	{
		if( !_pendingResult )
		{
			_close();
			_sendResultToController( FvFileChooser.CANCEL_OPTION );
		}
	}
	
	/**
	 * Closes the JFrame component
	 * 
	 * <p>Removes Blur effect and hack modal screen
	 */
	private function _close() : Void
	{
		_modal.hide();
		_frame.tryToClose();
		getController().unlockUI();
		
		FvFileChooserCommander.getInstance()._oEB.dispatchEvent( new BasicEvent( FvFileChooserEventList.CLOSE_CHOOSER ) );
	}
	
	/**
	 * Sends user result to the controller.
	 */
	private function _sendResultToController( type : Number ) : Void
	{
		getController().handleResultEvent( type, _storedSelection, _storedPath );	
	}
	
	/**
	 * Triggered when user click on JList component
	 */
	private function _handleListClick( source : JList, value : File, cell : ListCell, clickCount : Number ) : Void
	{
		if( value.isDirectory() )
		{
			if( clickCount == 2 ) _openDirectory( value );
			_previewComponent.load( null );
		}
		else 
		{
			if( ( clickCount == 2 ) && ( _type == FvFileChooserResources.OPEN ) ) _handleOpenItem();
			else
			{
				_setInputText( value );
				_previewComponent.load( value );
			}
		}
	}
	
	/**
	 * Triggered when user use keyboard on JList component
	 */
	private function _handleListKeyDown( source : JList ) : Void
	{
		var value : File = File( _list.getSelectedValue() );
		
		if( Key.isDown( Key.ENTER ) )
		{
			if( value.isDirectory() ) _openDirectory( value );
		}
	}
	
	/**
	 * Triggered the first time chooser is started
	 */
	private function _handleInit( source : JFrame ) : Void
	{
		getController().setCurrentDirectory();
	}
	
	/**
	 * Change currect directory to 'home'
	 */
	private function _handleMoveToHome( source : JButton ) : Void
	{
		getController().changeToHomeDirectory();
	}
	
	/**
	 * Change currect directory to 'parent' directory
	 */
	private function _handleMoveUp( source : JButton ) : Void
	{
		getController().changeToParentDirectory();
	}
	
	/**
	 * Process an upload
	 */
	private function _handleUpload( source : JButton ) : Void
	{
		_uploader.browse( FvFileChooser.BASE_PATH + _cmbLookIn.getSelectedItem().toString() );
	}
	
	/**
	 * Create a new folder in current directory
	 */
	private function _handleCreate( source : JButton ) : Void
	{
		_inputFolderDialog.open( FvFileChooserResources.getInstance().createFolderLabel, this, _onInputFolder );
	}
	
	private function _onInputFolder( result : String ) : Void
	{
		if( result )
		{
			var b : Boolean = Fever.io.createDirectory( _cmbLookIn.getSelectedItem().toString() + result );
			if( b ) _handleRefresh();
		}
	}
	
	/**
	 * Change currect directory to {@code source} directory
	 */
	private function _handleMoveTo( source : JComboBox ) : Void
	{
		if( !_pendingUpdate )
		{
			_resetSelection();
			getController().retreiveDirectory( String( source.getSelectedItem() ) );
		}
	}
	
	/**
	 * Refresh current directory
	 */
	private function _handleRefresh( source : FvLabelButton ) : Void
	{
		getController().rescanCurrentDirectory( String( _cmbLookIn.getSelectedItem() ) );
	}
	
	/**
	 * Triggered when user change file filter selection
	 */
	private function _handleChangeFilter( source : JComboBox ) : Void
	{
		_filterData( _data );
	}
	
	/**
	 * Sets input text value depending of Chooser selection mode 
	 * ( single / multiple )
	 */
	private function _setInputText( file : File ) : Void
	{
		var s : String = file.getName();
		
		if( getController().isMultiSelectionEnabled() 
			&& _list.getSelectedValues().length > 1 )
		{
			var a : Array = _list.getSelectedValues();
			var l : Number = a.length;
			s = "";
			for( var i : Number = 0; i < l; i++ )
			{
				s +=  a[i].getName() + ";";
			}
		}
		_inputFileName.setText( s );
	}
	
	/**
	 * Stores user selection properties
	 */
	private function _buildSelectionData( ) : Void
	{
		_storedPath = _cmbLookIn.getSelectedItem().toString();
		
		if( _type == FvFileChooserResources.SAVE )
		{
			var name : String = _inputFileName.getText();
			var item : File =  _getFileItemByFileName( name );
			
			if( !item )
			{
				item = File.create( _cmbLookIn.getSelectedItem().toString() + name );
			}
			
			_storedSelection = new Array( item );
		}
		else
		{
			if( getController().isMultiSelectionEnabled() && _list.getSelectedValues().length > 1 )
			{
				var a : Array = _inputFileName.getText().split( ";" );
				var selectionLength : Number = a.length;
				var result : Array = new Array();
				_storedSelection = new Array();
				
				for( var i : Number = 0; i < selectionLength; i++ ) 
				{
					var name : String = a[i];
					var item : File = _getFileItemByFileName( name );
					if( item )
					{
						_storedSelection.push( item );	
					}
				}
			}
			else
			{
			 	var item : File = _getFileItemByFileName( _inputFileName.getText() );
			 	_storedSelection = new Array( item );
			}
		}
	}
	
	private function _getFileItemByFileName( name : String ) : File
	{
		var l : Number = _dataFiltered.length;
		while(--l > -1)
		{
			var item : File = File( _dataFiltered[l] );
			if( name == item.getName() ) return item;
		}	
		return null;
	}
	
	/**
	 * Clear all stored selection
	 */
	private function _resetSelection() : Void
	{
		_inputFileName.setText();
		
		_storedPath = undefined;
		_storedSelection = undefined;
		
		_list.clearSelection();
	}
	
	/**
	 * Opens directory identify by the {@code o} parameter.
	 */
	private function _openDirectory( o : File ) : Void
	{
		getController().setCurrentDirectory( o );
	}
	
	/**
	 * Applies a filter on JList component
	 */
	private function _filterData( data : Array ) : Void
	{
		var filter : FileFilter = FileFilter( _cmbFileType.getSelectedItem() );
		getController().setFileFilter( filter );
		
		_data = data;
		_dataFiltered = new Array();
		var l : Number = _data.length;
		
		for( var i : Number = 0; i < l; i++ )
		{
			var file : File = _data[i];
			
			if( _type == FvFileChooserResources.BROWSE )
			{
				if( file.isDirectory() ) _dataFiltered.push( file );
			}
			else if( filter.accept( file ) ) _dataFiltered.push( file );
		}
		
		_list.setListData( _dataFiltered );
	}
	
	/**
	 * Indicates if all items defined in input text component 
	 * is available in current JList.
	 */
	private function _isAvailableFile() : Boolean
	{
		var a : Array = _inputFileName.getText().split( ";" );		var selectionLength : Number = a.length;
		var b : Boolean = true;
		
		for( var i : Number = 0; i < selectionLength; i++ )
		{
			var name : String = a[i];
			if( name != "" ) b = ( b &&_containsItemName( a[i] ) );
		}
		
		return b;
	}
	
	/**
	 * checks if passed-in {@code name} exists in current JList model
	 */
	private function _containsItemName( name : String ) : Boolean
	{
		var l : Number = _dataFiltered.length;
		while(--l > -1)
		{
			if( name == File( _dataFiltered[l] ).getName() ) return true;
		}	
		return false;
	}
	
	private function _onUploadStart( event : FileUploaderEvent ) : Void
	{
		FeverController.getInstance().broadcastEvent( new BooleanEvent( FeverEventList.onLockInteractionEVENT, true ) );
		
		_lockUpload.dispose();
		_lockUpload = null;
		
		_lockUpload = new ModalScreen( );
		_lockUpload.show();
		
		_title = _frame.getTitle();
		_frame.setTitle( FvFileChooserResources.getInstance().uploadLabel + " " + event.getFileName() );
	}
	
	private function _onUploadProgress( event : FileUploaderEvent ) : Void
	{
		_frame.setTitle( FvFileChooserResources.getInstance().uploadLabel + " " + event.getFileName() + " ( " + event.getPercent() + " % )" );
	}
	
	private function _onUploadComplete( event : FileUploaderEvent ) : Void
	{
		_onUploadFinish();
		getController().rescanCurrentDirectory( String( _cmbLookIn.getSelectedItem() ) );
	}
	
	private function _onUpLoadError( event : FileUploaderEvent ) : Void
	{
		_onUploadFinish();
	}
	
	private function _onUploadFinish() : Void
	{
		_frame.setTitle( _title );
		_lockUpload.dispose();
		_lockUpload = null;
		
		FeverController.getInstance().broadcastEvent( new BooleanEvent( FeverEventList.onLockInteractionEVENT, false ) );
	}
}